package com.sun.customer.service;

import com.sun.customer.manager.LocalManager;
import com.sun.customer.mapper.local.LocalRoleBaseDOMapper;
import com.sun.customer.mapper.local.LocalUserBaseDOMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

/**
 * Created by yingsy on 2021-01-22.
 *
 * Propagation.REQUIRED:如果有事务,那么加入事务,没有的话新创建一个
 * Propagation.NOT_SUPPORTED:这个方法不开启事务
 * Propagation.REQUIREDS_NEW:不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
 * Propagation.MANDATORY:必须在一个已有的事务中执行,否则抛出异常
 * Propagation.NEVER:不能在一个事务中执行,就是当前必须没有事务,否则抛出异常
 * Propagation.SUPPORTS:若当前存在事务,则在事务中运行.否则以非事务形式运行
 * Propagation.NESTED:如果当前存在事务,则运行在一个嵌套的事务中,如果当前没有事务,则按照REQUIRED属性执行.
 * 它只对DataSourceTransactionManager事务管理器起效
 *
 * TransactionDefinition.ISOLATION_DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别.
 * TransactionDefinition.ISOLATION_READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据.该级别不能防止脏读,不可重复读和幻读,因此很少使用该隔离级别.比如PostreSQL实际上并没有此级别.
 * TransactionDefinition.ISOLATION_READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据.该级别可以防止脏读,这也是大多数情况下的推荐值.
 * TransactionDefinition.ISOLATION_REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同.该级别可以防止脏读和不可重复读.
 * TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读.但是这将严重影响程序的性能,通常情况下也不会用到该级别.
 */
@Service
@Slf4j
public class TestServiceImpl {

    @Autowired
    private LocalManager localManager;
    @Autowired
    private LocalRoleBaseDOMapper localRoleBaseDOMapper;
    @Autowired
    private LocalUserBaseDOMapper localUserBaseDOMapper;

    //默认事务 REQUIRED 都会回滚事务
    @Transactional(rollbackFor = Throwable.class)
    public String test1(Integer num) {
        String s = UUID.randomUUID().toString();
        log.info("name is {}",s);
        localManager.updateRoleNameById(num, s);
        localManager.updateUserNameById(num, s);
        if(1000%num == 0){
            return s;
        }
        return s;
    }

    @Transactional(rollbackFor = Throwable.class)
    public String test2(Integer num) {
        String s = UUID.randomUUID().toString();
        log.info("name is {}",s);
        localRoleBaseDOMapper.updateNameById(s);
        if(1000%num == 0){
            return "True-"+s;
        }
        localUserBaseDOMapper.updateNameById(s);
//        if(1000%num == 0){
//            return "True-"+s;
//        }
        return s;
    }

    //REQUIRES_NEW 会新启一个事务
    //REQUIRED 有事务，则会加入事务
    @Transactional(rollbackFor = Throwable.class)
    public String test3(Integer num) {
        String s = UUID.randomUUID().toString();
        log.info("name is {}",s);
        localManager.updateRoleNameById3(num, s);
        localManager.updateUserNameById3(num, s);
        if(1000%num == 0){
            return s;
        }
        return s;
    }
}
